package function

import (
	"bytes"
	"core/component/logger"
	"encoding/csv"
	"encoding/json"
	"fmt"
	"math/rand"
	"net/http"
	"os"
	"strconv"
	"strings"
	"sync"
)

type DingDingText struct {
	Content string `json:"content"`
}

type DingDingAt struct {
	IsAtAll bool `json:"isAtAll"`
}

type PanicDingDingNotify struct {
	MsgType string        `json:"msgtype"`
	Text    *DingDingText `json:"text"`
	At      *DingDingAt   `json:"at"`
}

func WritePanic(stackMsg string, err interface{}) {
	logger.Errorf("[异常] player goroutine出错 err:%v stack:\n%v", err, stackMsg)

	dingdingMsg := &PanicDingDingNotify{
		MsgType: "text",
		Text:    &DingDingText{},
		At:      &DingDingAt{IsAtAll: false},
	}

	content := fmt.Sprintf("ip:%v user:%v errType:%v error:%v\n content:%v", "root", "miaoqing", "", err, stackMsg)
	dingdingMsg.Text.Content = content

	url := "https://oapi.dingtalk.com/robot/send?access_token=72aa8fd96a97dd8f80f32d404305236be7312b42767cd5e9b73e7f6ba032b9ec"
	jsonValue, err := json.Marshal(dingdingMsg)
	if err != nil {
		logger.Error(err)
		return
	}
	http.Post(url, "application/json", bytes.NewBuffer(jsonValue))
}

func CalcSyncMapLen(m *sync.Map) (l int32) {
	m.Range(func(key, value interface{}) bool {
		l++
		return true
	})
	return
}

// SplitStringToUint32Slice string转整数切片 example:"1001|1002" -> []uint32{1001, 1002}
func SplitStringToUint32Slice(src string, sep string) []uint32 {
	strSlice := strings.Split(src, sep)
	var uint32Slice []uint32
	//uint32Slice := make([]uint32, 0, len(strSlice))
	for _, item := range strSlice {
		value, err := strconv.ParseUint(item, 10, 32)
		if err != nil {
			continue
		}
		uint32Slice = append(uint32Slice, uint32(value))
	}

	return uint32Slice
}

func IpAddressStringToUint64(ipaddr string) uint64 {
	var digit uint64
	data := strings.Split(ipaddr, ":")
	port := SplitStringToUint32Slice(data[1], ".")
	val := SplitStringToUint32Slice(data[0], ".")
	digit = uint64(val[0]<<24) | uint64(val[1]<<16) | uint64(val[2]<<8) | uint64(val[3])
	digit = digit<<32 | uint64(port[0])
	return digit
}

func CheckIDInSliceString(id string, ids []string) (bool, int) {
	for index, val := range ids {
		if val == id {
			return true, index
		}
	}
	return false, 0
}

func RandSyncMap(m *sync.Map) any {
	arr := make([]any, 0)
	m.Range(func(key, value any) bool {
		arr = append(arr, key)
		return true
	})
	if len(arr) == 0 {
		return nil
	}
	return arr[rand.Intn(len(arr))]
}

func saveToCSV(wireteString [][]string, name string) {
	var filename = fmt.Sprintf("%s.csv", name)
	var f *os.File
	var err1 error

	f, err1 = os.Create(filename) //创建文件
	if err1 != nil {
		logger.Errorf("写入csv错误 %v", err1)
		return
	}
	defer f.Close()

	f.WriteString("\xEF\xBB\xBF") // 写入UTF-8 BOM

	w := csv.NewWriter(f) //创建一个新的写入文件流
	w.WriteAll(wireteString)
	w.Flush()

	logger.Infof("写入csv成功 %v", filename)
}
